/**
 * UIImage+GTExtension.m
 *
 * The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");
 * you may not use this file except in compliance with the License. You may obtain a copy of the License 
 * at http://www.mozilla.org/MPL/
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
 * either express or implied. See the License for the specific language governing rights and limitations 
 * under the License.
 *
 * The Original Code is gcast-toolbox4iphone.
 *
 * The Initial Developers of the Original Code is Giannandrea Castaldi.
 */

#import "UIImage+GTExtension.h"

@implementation UIImage (GTExtension)

- (UIImage*)paintWithColor:(UIColor*)color {
  //  UIGraphicsBeginImageContext(self.size);
  GTGraphicsBeginRetinaAwareImageContext(self.size);
  
  CGRect contextRect;
  contextRect.origin.x = 0.0f;
  contextRect.origin.y = 0.0f;
  contextRect.size = self.size;
  // Retrieve source image and begin image context
  CGSize itemImageSize = self.size;
  CGPoint itemImagePosition; 
  itemImagePosition.x = ceilf((contextRect.size.width - itemImageSize.width) / 2);
  itemImagePosition.y = ceilf((contextRect.size.height - itemImageSize.height) );
  
  //  UIGraphicsBeginImageContext(contextRect.size);
  GTGraphicsBeginRetinaAwareImageContext(contextRect.size);
  
  CGContextRef c = UIGraphicsGetCurrentContext();
  CGContextBeginTransparencyLayer(c, NULL);
  CGContextScaleCTM(c, 1.0, -1.0);
  CGContextClipToMask(c, CGRectMake(itemImagePosition.x, -itemImagePosition.y, itemImageSize.width, -itemImageSize.height), [self CGImage]);
  
  [color set];
  
  contextRect.size.height = -contextRect.size.height;
  contextRect.size.height -= 15;
  CGContextFillRect(c, contextRect);
  CGContextEndTransparencyLayer(c);
  
  UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  return result;
}

- (CGContextRef)createARGBBitmapContextFromImage:(CGImageRef)inImage {
CGContextRef    context = NULL;
CGColorSpaceRef colorSpace;
void*           bitmapData;
int             bitmapByteCount;
int             bitmapBytesPerRow;

// Get image width, height. We'll use the entire image.
size_t pixelsWide = CGImageGetWidth(inImage);
size_t pixelsHigh = CGImageGetHeight(inImage);

// Declare the number of bytes per row. Each pixel in the bitmap in this
// example is represented by 4 bytes; 8 bits each of red, green, blue, and
// alpha.
bitmapBytesPerRow   = (pixelsWide * 4);
bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);

// Use the generic RGB color space.
colorSpace = CGColorSpaceCreateDeviceRGB();//CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
if (colorSpace == NULL)
{
  fprintf(stderr, "Error allocating color space\n");
  return NULL;
}

// Allocate memory for image data. This is the destination in memory
// where any drawing to the bitmap context will be rendered.
bitmapData = malloc( bitmapByteCount );
if (bitmapData == NULL)
{
  fprintf (stderr, "Memory not allocated!");
  CGColorSpaceRelease( colorSpace );
  return NULL;
}

// Create the bitmap context. We want pre-multiplied ARGB, 8-bits
// per component. Regardless of what the source image format is
// (CMYK, Grayscale, and so on) it will be converted over to the format
// specified here by CGBitmapContextCreate.
context = CGBitmapContextCreate (bitmapData,
                                 pixelsWide,
                                 pixelsHigh,
                                 8,      // bits per component
                                 bitmapBytesPerRow,
                                 colorSpace,
                                 kCGImageAlphaPremultipliedFirst);
if (context == NULL)
{
  free (bitmapData);
  fprintf (stderr, "Context not created!");
}

// Make sure and release colorspace before returning
CGColorSpaceRelease( colorSpace );

return context;
}

- (UIColor*)getPixelColorAtPoint:(CGPoint)point {
  GTGraphicsBeginRetinaAwareImageContext(self.size);
  
  UIColor *color = nil;
  CGImageRef inImage = self.CGImage;
  CGContextRef context = [self createARGBBitmapContextFromImage:inImage];
  
  if(context == NULL)
    return nil;
  
  CGRect rect = CGRectMake(0.0, 0.0, CGImageGetWidth(inImage), CGImageGetHeight(inImage));
  
  // Draw the image to the bitmap context. Once we draw, the memory
  // allocated for the context for rendering will then contain the
  // raw image data in the specified color space.
  CGContextDrawImage(context, rect, inImage); 
  
  // Now we can get a pointer to the image data associated with the bitmap
  // context.
  unsigned char* data = CGBitmapContextGetData(context);
  if (data != NULL) {
    //offset locates the pixel in the data from x,y.
    //4 for 4 bytes of data per pixel, w is width of one row of data.
    CGFloat scaledX = point.x * GTGraphicsScaleFactor();
    CGFloat scaledY = point.y * GTGraphicsScaleFactor();
    int offset = 4*((rect.size.width*round(scaledY))+round(scaledX));
    int alpha =  data[offset];
    int red = data[offset+1];
    int green = data[offset+2];
    int blue = data[offset+3];
    // NSLog(@"offset: %i colors: RGB A %i %i %i  %i ",offset,red,green,blue,alpha);
    color = [UIColor colorWithRed:(red/255.0f) green:(green/255.0f) blue:(blue/255.0f) alpha:(alpha/255.0f)];
  }
  
  // When finished, release the context
  CGContextRelease(context);
  
  // Free image data memory for the context
  if (data) {
    free(data);
  }
  
  return color;
}

@end


void GTGraphicsBeginRetinaAwareImageContext(CGSize size) {
  UIGraphicsBeginImageContextWithOptions(size, NO, GTGraphicsScaleFactor());
}

CGFloat GTGraphicsScaleFactor() {
	static CGFloat scale = -1.0;
	if (scale < 0.0) {
		UIScreen *screen = [UIScreen mainScreen];
    scale = [screen scale];
	}
  return scale;
}

